package com.elf.gwt.common.client.subcomponent;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.elf.gwt.common.client.CommonComponentController;
import com.elf.gwt.common.client.GWTCommerceCommonConstants;
import com.elf.gwt.common.client.callback.SubComponentCallback;
import com.elf.gwt.common.client.model.AccountMetaModel;
import com.elf.gwt.common.client.model.AccountModel;
import com.elf.gwt.common.client.model.AddressModel;
import com.elf.gwt.common.client.model.ContactUsMetaModel;
import com.elf.gwt.common.client.model.ContactUsModel;
import com.elf.gwt.common.client.model.CountryModel;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

/**
 *  Subcomponent for captcha
 */
public class ContactUsSubComponent extends CommonSubComponent
{
	public static final String Submit = "Submit";
	protected String action = "";
	protected HashMap<String, Widget> elements = null;

	protected ListBox addressListBox = null;
	RadioButton genderMButton = null;
	RadioButton genderFButton = null;
	protected TextBox firstname = null;
	protected TextBox lastname = null;
	protected TextBox emailBox = null;
	protected TextBox companyBox = null;
	protected ListBox countryListBox = null;
	protected TextBox streetBox = null;
	protected TextBox suburbBox = null;
	protected TextBox cityBox = null;
	protected ListBox stateListBox = null;
	protected TextBox postCodeBox = null;
	protected TextBox phoneBox = null;
	protected ListBox subjectBox = null;
	protected TextArea commentBox = null;

	protected CommonComponentController controller = null;
	protected ContactUsMetaModel contactUsMetaModel = null;
	protected ContactUsModel contactUsModel = null;
	protected AccountModel accountModel = null;
	protected AccountMetaModel accountMetaModel = null;

	/**
	 * Constructor
	 */
	public ContactUsSubComponent(
			CommonComponentController controller, 
			ContactUsMetaModel contactUsMetaModel, 
			ContactUsModel contactUsModel, 
			AccountModel accountModel,
			AccountMetaModel accountMetaModel,
			SubComponentCallback subComponentCallback)
	{
		super("ContactUsComponent", null, subComponentCallback);
		elements = new HashMap<String, Widget>();
		this.controller = controller;
		this.contactUsMetaModel = contactUsMetaModel;
		this.contactUsModel = contactUsModel;
		this.accountModel = accountModel;
		this.accountMetaModel = accountMetaModel;
	}

	public void build()
	{
		clear();
		elements.clear();
		int pc = contactUsModel.getProcessCode();
		GWTCommerceCommonConstants constants = controller.getCommonConstants();

		if (pc == 1) {
			add(new Label(constants.ContactUsSuccessfulSubmit()));
		}
		else {
			if (contactUsModel.getProcessCode() < 0) {
				HTML warningLabel = new HTML();
				warningLabel.setStyleName("WarningLabel");
				warningLabel.addStyleName(handle + "WarningLabel");
				if (pc == -3)
				{
					warningLabel.setHTML(constants.CaptchaSessionNotFound() + "<br/>");
				}
				else if (pc == -1 || pc == -4)
				{
					warningLabel.setHTML(constants.CaptchaCodeNotMatch() + "<br/>");
				}
				else if (pc == -7)
				{
					warningLabel.setHTML(constants.ContactUsInvalidEmail() + "<br/>");
				}
				else
				{
					warningLabel.setHTML("processCode = " + pc + "<br/>");
				}

				add(warningLabel);
			}

			Grid requiredGrid = new Grid(1,1);
			requiredGrid.setWidth("100%");
			requiredGrid.getCellFormatter().setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_RIGHT);
			requiredGrid.getCellFormatter().setStyleName(0, 0, "WarningLabel");
			requiredGrid.getCellFormatter().addStyleName(0, 0, handle + "WarningLabel");
			requiredGrid.setText(0, 0, constants.ContactUsRequired());
			add(requiredGrid);

			if (accountModel != null && accountModel.getId() > 0) {
				if (addressListBox == null) {
					addressListBox = new ListBox();
					List<AddressModel> addresses = accountModel.getAddresses();

					Iterator<AddressModel> iter1 = addresses.iterator();
					int i = 0;
					while(iter1.hasNext())
					{
						AddressModel model = iter1.next();
						String address = "";
						if (model.getCompany() != null && model.getCompany().length() > 0) address += model.getCompany() + ", ";
						address += model.getFirstname() + " " + model.getLastname() + ", ";
						address += model.getStreet() + ", ";
						if (model.getSuburb() != null && model.getSuburb().length() > 0)  address += model.getSuburb() + ", ";
						if (model.getState() != null && model.getState().length() > 0)
							address += model.getCity() + ", " + model.getState() + " " + model.getPostcode() + ", ";
						else
							address += model.getCity() + ", " + model.getPostcode() + ", ";
						address += model.getCountry();

						addressListBox.addItem(address, String.valueOf(model.getId()));
						addressListBox.setItemSelected(i, model.isDefaultAddress());
						i++;
					}
				}
				elements.put("addressId", addressListBox);
				Grid contactGrid = new Grid(1,3);
				contactGrid.setWidth("100%");
				contactGrid.setStyleName(handle + "SubPanel");
				contactGrid.getColumnFormatter().setStyleName(0, handle + "SubPanelCol0");
				thisComponent.add(contactGrid);
				CommonUtils.addGridWidget(handle, 0, addressListBox, contactGrid, "address", constants.ContactUsAddress(), constants.ContactUsAddressText());

			}
			else {
				int gridrows = 10;
				if (accountMetaModel.isDisplayGender()) gridrows++;
				if (accountMetaModel.isDisplayCompany()) gridrows++;
				if (accountMetaModel.isDisplaySuburb()) gridrows++;

				Grid contactGrid = new Grid(gridrows,3);
				contactGrid.setWidth("100%");
				contactGrid.setStyleName(handle + "SubPanel");
				contactGrid.getColumnFormatter().setStyleName(0, handle + "SubPanelCol0");
				thisComponent.add(contactGrid);

				int gridrow = 0;

				if (accountMetaModel.isDisplayGender())
				{
					if (genderMButton == null) {
						genderMButton = new RadioButton("gender1", constants.ContactUsMale());
						genderFButton = new RadioButton("gender1", constants.ContactUsFemale());
					}
					elements.put("genderM", genderMButton);
					elements.put("genderF", genderFButton);
					HorizontalPanel genderPanel = new HorizontalPanel();
					genderPanel.add(genderMButton);
					genderPanel.add(genderFButton);

					CommonUtils.addGridWidget(handle, gridrow, genderPanel, contactGrid, "gender", constants.ContactUsGender(), constants.ContactUsGenderText());
					gridrow++;
				}

				if (firstname == null) {
					firstname = new TextBox(); 
				}
				elements.put("firstname", firstname);
				if (pc > -1) firstname.setText("");
				CommonUtils.addGridWidget(handle, gridrow, firstname, contactGrid, "firstname", constants.ContactUsFirstName(), constants.ContactUsFirstNameText());
				gridrow++;

				if (lastname == null) {
					lastname = new TextBox(); 
				}
				elements.put("lastname", lastname);
				if (pc > -1) lastname.setText("");
				CommonUtils.addGridWidget(handle, gridrow, lastname, contactGrid, "lastname", constants.ContactUsLastName(), constants.ContactUsLastNameText());
				gridrow++;

				if (emailBox == null) {
					emailBox = new TextBox(); 
				}
				elements.put("email", emailBox);
				if (pc > -1) emailBox.setText("");
				CommonUtils.addGridWidget(handle, gridrow, emailBox, contactGrid, "email", constants.ContactUsEmail(), constants.ContactUsEmailText());
				gridrow++;

				if (accountMetaModel.isDisplayCompany())
				{
					if (companyBox == null) {
						companyBox = new TextBox();
					}
					elements.put("company", companyBox);
					if (pc > -1) companyBox.setText("");
					CommonUtils.addGridWidget(handle, gridrow, companyBox, contactGrid, "company", constants.ContactUsCompany(), constants.ContactUsCompanyText());
					gridrow++;
				}

				if (countryListBox == null) {
					countryListBox = new ListBox();
					countryListBox.addChangeHandler(new ChangeHandler() {
						public void onChange(ChangeEvent event) {
							if (accountMetaModel.isDisplayState())
							{
								CountryModel cmodel = accountMetaModel.getCountryModels().get(countryListBox.getSelectedIndex());
								String countryName = cmodel.getName();
								if (accountMetaModel.isDisplayState()) CommonUtils.updateStateListBox(countryName, null, accountMetaModel.getCountryModels(), stateListBox);	
							}
						}
					});
					Iterator<CountryModel> iter = accountMetaModel.getCountryModels().iterator();
					int i = 0;
					while(iter.hasNext())
					{
						CountryModel cmodel = iter.next();
						countryListBox.addItem(cmodel.getName(),cmodel.getName());
						AddressModel amodel = accountModel.getDefaultAddress();
						if (cmodel.getName().equals(amodel.getCountry()))
							countryListBox.setItemSelected(i, true);
						else
							countryListBox.setItemSelected(i, false);
						i++;
					}
				}
				elements.put("country", countryListBox);
				CommonUtils.addGridWidget(handle, gridrow, countryListBox, contactGrid, "country", constants.ContactUsCountry(), constants.ContactUsCountryText());
				gridrow++;

				if (streetBox == null) {
					streetBox = new TextBox(); 
				}
				elements.put("street", streetBox);
				CommonUtils.addGridWidget(handle, gridrow, streetBox, contactGrid, "street_address", constants.ContactUsStreetAddress(), constants.ContactUsStreetAddressText());
				gridrow++;

				if (accountMetaModel.isDisplaySuburb())
				{
					if (suburbBox == null) {
						suburbBox = new TextBox(); 
					}
					elements.put("suburb", suburbBox);
					CommonUtils.addGridWidget(handle, gridrow, suburbBox, contactGrid, "suburb", constants.ContactUsSuburb(), constants.ContactUsSuburbText());
					gridrow++;
				}

				if (cityBox == null) {
					cityBox = new TextBox(); 
				}
				elements.put("city", cityBox);
				CommonUtils.addGridWidget(handle, gridrow, cityBox, contactGrid, "city", constants.ContactUsCity(), constants.ContactUsCityText());
				gridrow++;

				if (accountMetaModel.isDisplayState())
				{
					if (stateListBox == null) {
						stateListBox = new ListBox();
						CountryModel cmodel = accountMetaModel.getCountryModels().get(countryListBox.getSelectedIndex());
						String countryName = cmodel.getName();
						AddressModel amodel = accountModel.getDefaultAddress();
						CommonUtils.updateStateListBox(countryName, amodel.getState(), accountMetaModel.getCountryModels(), stateListBox);
					}
					elements.put("state", stateListBox);
					CommonUtils.addGridWidget(handle, gridrow, stateListBox, contactGrid, "state", constants.ContactUsState(), constants.ContactUsStateText());
					gridrow++;
				}

				if (postCodeBox == null) {
					postCodeBox = new TextBox(); 
				}
				elements.put("postcode", postCodeBox);
				CommonUtils.addGridWidget(handle, gridrow, postCodeBox, contactGrid, "postcode", constants.ContactUsPostCode(), constants.ContactUsPostCodeText());
				gridrow++;

				if (phoneBox == null) {
					phoneBox = new TextBox(); 
				}
				elements.put("phone", phoneBox);
				if (pc > -1) phoneBox.setText("");
				CommonUtils.addGridWidget(handle, gridrow, phoneBox, contactGrid, "phone", constants.ContactUsPhone(), constants.ContactUsPhoneText());
				gridrow++;
			}

			Grid subjectGrid = new Grid(1,3);
			subjectGrid.setWidth("100%");
			subjectGrid.setStyleName(handle + "SubPanel");
			subjectGrid.getColumnFormatter().setStyleName(0, handle + "SubPanelCol0");
			thisComponent.add(subjectGrid);

			if (subjectBox == null) {
				subjectBox = new ListBox();
				subjectBox.addItem(constants.ContactUsSubjectBrochureRequest(),"1");
				subjectBox.addItem(constants.ContactUsSubjectOrderInquiry(),"2");
				subjectBox.addItem(constants.ContactUsSubjectQuoteRequest(),"3");
				subjectBox.addItem(constants.ContactUsSubjectFeedback(),"4");
			}
			elements.put("subject", subjectBox);
			if (pc > -1) subjectBox.setItemSelected(0, true);
			CommonUtils.addGridWidget(handle, 0, subjectBox, subjectGrid, "subject", constants.ContactUsSubject(), constants.ContactUsSubjectText());

			if (commentBox == null) {
				commentBox = new TextArea(); 
				commentBox.setVisibleLines(5);
				commentBox.setWidth("100%");
			}
			if (pc > -1) commentBox.setText("");
			elements.put("comment", commentBox);

			Grid commentGrid = new Grid(2,1);
			commentGrid.setWidth("100%");
			commentGrid.setText(0,0, constants.ContactUsComments());
			commentGrid.setWidget(1,0,commentBox);
			commentGrid.getCellFormatter().setWidth(1, 0, "100%");
			commentGrid.getCellFormatter().setWidth(0, 0, "100%");
			add(commentGrid);

			if (accountModel == null || accountModel.getId() < 1) {
				CaptchaSubComponent captchaSubComponent = new CaptchaSubComponent(controller);
				captchaSubComponent.build();
				elements.put("captcha", captchaSubComponent);
				add(captchaSubComponent);
			}

			Button submitButton = new Button(constants.ContactUsSubmit(), submitHandler);
			submitButton.addStyleName("ComponentLink");
			add(submitButton);
		}

	}

	protected ClickHandler submitHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{

			StringBuffer warningText = new StringBuffer();
			GWTCommerceCommonConstants constants = controller.getCommonConstants();

			if (accountModel == null || accountModel.getId() < 1) {
				TextBox firstnameBox = (TextBox)elements.get("firstname");
				if (firstnameBox != null) {
					warningText = CommonUtils.lengthWarning(constants, warningText, firstnameBox, 
							constants.ContactUsFirstName(), accountMetaModel.getEntryFirstnameLengthMin());
				}
				TextBox lastnameBox = (TextBox)elements.get("lastname");
				if (lastnameBox != null) {
					warningText = CommonUtils.lengthWarning(constants, warningText, lastnameBox, 
							constants.ContactUsLastName(), accountMetaModel.getEntryLastnameLengthMin());
				}

				TextBox emailBox = (TextBox)elements.get("email");
				if (emailBox != null) {
					warningText = CommonUtils.lengthWarning(constants, warningText, emailBox, 
							constants.ContactUsEmail(), accountMetaModel.getEntryEmailAddressLengthMin());
				}

				TextBox streetBox = (TextBox) elements.get("street");
				if (streetBox != null) {
					warningText = CommonUtils.lengthWarning(constants, warningText, streetBox, 
							constants.ContactUsStreetAddress(), accountMetaModel.getEntryStreetAddressLengthMin());
				}
				
				TextBox postCodeBox = (TextBox) elements.get("postcode");
				if (postCodeBox != null) {
					warningText = CommonUtils.lengthWarning(constants, warningText, postCodeBox, 
							constants.ContactUsPostCode(), accountMetaModel.getEntryPostCodeLengthMin());
				}
				
				TextBox cityBox = (TextBox) elements.get("city");
				if (cityBox != null) {
					warningText = CommonUtils.lengthWarning(constants, warningText, cityBox, 
							constants.ContactUsCity(), accountMetaModel.getEntryCityLengthMin());
				}
				
				TextBox phoneBox = (TextBox)elements.get("phone");
				if (phoneBox != null) {
					warningText = CommonUtils.lengthWarning(constants, warningText, phoneBox, 
							constants.ContactUsPhone(), accountMetaModel.getEntryTelephoneNumberLengthMin());
				}

			}
			if (warningText.length() > 0)
				Window.alert(warningText.toString());
			else
			{
				action = Submit;
				callback.onSuccess(thisComponent);
			}
		}
	};

	public String getAction() {
		return action;
	}

	public HashMap<String, Widget> getElements() {
		return elements;
	}

	public AccountModel getAccountModel() {
		return accountModel;
	}

	public void setAccountModel(AccountModel accountModel) {
		this.accountModel = accountModel;
	}

	public AccountMetaModel getAccountMetaModel() {
		return accountMetaModel;
	}

	public void setAccountMetaModel(AccountMetaModel accountMetaModel) {
		this.accountMetaModel = accountMetaModel;
	}
}
